package ecpay

import (
	"context"
	"net/http"
)

const (
	apiCreateOrder = "v1/create_order"
	apiQueryOrder = "v1/query_order"
	apiCreateRefund = "v1/create_refund"
)



// CreateOrderRequest 创建订单请求
type CreateOrderRequest struct {
	baseBody
	AppID       string `json:"app_id,omitempty"`       // 必传 	小程序平台分配的 appId
	OutOrderNo  string `json:"out_order_no,omitempty"` // 必传 	商户订单号，必须保证每次预下单订单号唯一，否则会报错
	TotalAmount int    `json:"total_amount,omitempty"` // 必传 	金额，整型（单位：分）
	Subject     string `json:"subject,omitempty"`      // 必传 	商户订单标题
	Body        string `json:"body,omitempty"`         // 必传 	商户订单详情
	ValidTime   int64  `json:"valid_time,omitempty"`   // 必传 	订单有效时间（单位：秒）注意：非时间戳
	NotifyURL   string `json:"notify_url,omitempty"`   // 选传	自定义回调地址，会覆盖平台中的设置，不会检查url的有效性，请自行确保回调地址可用
	CPExtra     string `json:"cp_extra,omitempty"`     // 选传	用户自定义字段，回调时回传，长度上限128
	DisableMsg  int    `json:"disable_msg,omitempty"`  // 选传 // 必传 否屏蔽支付消息（用于poi订单等需屏蔽），传入非0值后会屏蔽通知
	MsgPage     string `json:"msg_page,omitempty"`     // 选传	支付消息跳转页，默认为空，跳转小程序首页
}

// CreateOrderResponse 创建订单返回
type CreateOrderResponse struct {
	OrderInfo struct {
		OrderID    string `json:"order_id"`
		OrderToken string `json:"order_token"`
	} `json:"data"`
}

// CreateOrder 预下单
func (c Client) CreateOrder(ctx context.Context, req *CreateOrderRequest) (*CreateOrderResponse, error) {
	r, err := c.NewRequest(http.MethodPost, apiCreateOrder, req)
	if err != nil {
		return nil, err
	}
	resp := new(CreateOrderResponse)
	err = c.Do(ctx, r, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}

// QueryOrderRequest 查询订单请求
type QueryOrderRequest struct {
	baseBody
	AppID      string `json:"app_id,omitempty"`       // 必传	小程序平台分配的 app_id
	OutOrderNo string `json:"out_order_no,omitempty"` // 必传	商户订单号
}

// QueryOrderResponse 查询订单返回
type QueryOrderResponse struct {
	PaymentInfo struct {
		TotalFee         int    `json:"TotalFee"`
		OrderStatus      string `json:"OrderStatus"`// PROCESSING-处理中|SUCCESS-成功|FAIL-失败|TIMEOUT-超时
		PayTime          string `json:"PayTime"`// 支付时间
		Way              int    `json:"Way"`
		ChannelNo        string `json:"ChannelNo"`// 渠道单号
		ChannelGatewayNo string `json:"ChannelGatewayNo"` //渠道网关号
	}

}
// QueryOrder 查询订单
func (c Client) QueryOrder(ctx context.Context, req *QueryOrderRequest) (*QueryOrderResponse, error) {
	r, err := c.NewRequest(http.MethodPost, apiQueryOrder, req)
	if err != nil {
		return nil, err
	}
	resp := new(QueryOrderResponse)
	err = c.Do(ctx, r, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}

// CreateRefundRequest 创建退订单请求
type CreateRefundRequest struct {
	baseBody
	AppID        string `json:"app_id,omitempty"`        // 必传	小程序平台分配的 app_id
	OutOrderNo   string `json:"out_order_no,omitempty"`  // 必传	商户订单号
	OutRefundNo  string `json:"out_refund_no,omitempty"` // 必传	商户退款单号
	TotalAmount  int64  `json:"total_amount,omitempty"`  // 必传	金额，整型（单位：分）
	RefundAmount int64  `json:"refund_amount,omitempty"` // 必传	退款金额
	Reason       string `json:"reason,omitempty"`        // 必传	退款理由
	NotifyURL    string `json:"notify_url,omitempty"`    // 选传	自定义回调Url，非必传，会覆盖平台回调地址
	CPExtra      string `json:"cp_extra,omitempty"`      // 选传	自定义字段，回调时传回
	DisableMsg   int64  `json:"disable_msg,omitempty"`   // 选传 // 必传否屏蔽退款消息（用于poi订单等需屏蔽），传入非0值后会屏蔽通知
	MsgPage      string `json:"msg_page,omitempty"`      // 选传	退款消息跳转页，默认为空，跳转小程序首页
}

// CreateRefundResponse 创建退订单返回
type CreateRefundResponse struct {
	RefundNo string `json:"refund_no"` // 平台生成退款单号
}
// CreateRefund 创建退订单
func (c Client) CreateRefund(ctx context.Context, req *CreateRefundRequest) (*CreateRefundResponse, error) {
	r, err := c.NewRequest(http.MethodPost, apiCreateRefund, req)
	if err != nil {
		return nil, err
	}
	resp := new(CreateRefundResponse)
	err = c.Do(ctx, r, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}

// QueryRefundRequest 查询退订单请求
type QueryRefundRequest struct {
	baseBody
	AppID       string `json:"app_id,omitempty"`        // 必传	小程序平台分配的 app_id
	OutRefundNo string `json:"out_refund_no,omitempty"` // 必传	商户侧，外部退款单号
}

// QueryRefundResponse 查询退订单返回
type QueryRefundResponse struct {
	RefundInfo struct{
		RefundAmount	string	// 退款金额
		RefundNo	string	// 小程序侧退款单号
		RefundStatus	string	// 退款状态，包含SUCCESS ，FAIL ，PROCESSING
	} `json:"refundInfo"`

}

// QueryRefund 查询退订单
func (c Client) QueryRefund(ctx context.Context, req *QueryRefundRequest) (*QueryRefundResponse, error) {
	r, err := c.NewRequest(http.MethodPost, apiCreateOrder, req)
	if err != nil {
		return nil, err
	}
	resp := new(QueryRefundResponse)
	err = c.Do(ctx, r, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}

